#include "message_handler.h"
#include "database.h"
#include "response_handler.h"
#include "utils.h"
#include <json-c/json.h>
#include <libwebsockets.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

extern sqlite3 *db;

// 客户端消息处理
static void handle_message(struct lws *wsi, struct per_session_data__custom *pss,
                           VHostData *vhd, struct json_object *json) {
    // 检查认证状态
    if (!pss->client->is_authenticated) {
        send_response(wsi, "error", "unauthenticated", "请先进行身份认证");
        return;
    }

    struct json_object *content_obj, *username_obj;
    if (json_object_object_get_ex(json, "content", &content_obj) &&
        json_object_object_get_ex(json, "username", &username_obj)) {

        const char *username = json_object_get_string(username_obj);
        const char *content = json_object_get_string(content_obj);

        // 验证用户名是否匹配
        if (strcmp(username, pss->client->username) != 0) {
            send_response(wsi, "error", "invalid_user", "用户名不匹配");
            return;
        }

        struct json_object *broadcast = json_object_new_object();
        json_object_object_add(broadcast, "action", json_object_new_string("message"));
        json_object_object_add(broadcast, "username", json_object_new_string(username));
        json_object_object_add(broadcast, "content", json_object_new_string(content));

        char timestamp[128];
        time_t now = time(NULL);
        strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
        json_object_object_add(broadcast, "timestamp", json_object_new_string(timestamp));

        const char *broadcast_str = json_object_to_json_string(broadcast);
        broadcast_message(vhd, broadcast_str, wsi);
        json_object_put(broadcast);

        lwsl_info("%s: %s\n", pss->client->username, content);
    } else {
        send_response(wsi, "error", "missing_content", "消息缺少content字段");
    }
}

// 处理Token认证
static void handle_authenticate(struct lws *wsi, struct per_session_data__custom *pss,
                                struct json_object *json) {
    struct json_object *token_obj, *username_obj;
    if (!json_object_object_get_ex(json, "token", &token_obj) ||
        !json_object_object_get_ex(json, "username", &username_obj)) {
        send_response(wsi, "authResponse", "error", "缺少token或username字段");
        return;
    }

    const char *token = json_object_get_string(token_obj);
    const char *username = json_object_get_string(username_obj);

    // 验证Token
    if (verify_jwt_token(token, secret)) {
        // 解析payload获取用户ID
        struct json_object *payload = parse_jwt_payload(token);
        if (payload) {
            int user_id = get_user_id_from_payload(payload);
            if (user_id > 0) {
                // 验证用户名是否匹配
                const char *token_username = get_username_from_payload(payload);
                if (token_username && strcmp(token_username, username) == 0) {
                    // 设置客户端认证状态
                    pss->client->is_authenticated = 1;
                    strncpy(pss->client->username, username, sizeof(pss->client->username) - 1);
                    pss->client->user_id = user_id;

                    send_response(wsi, "authResponse", "success", "身份认证成功");
                    lwsl_info("%s 认证成功\n", username);

                } else {
                    send_response(wsi, "authResponse", "error", "用户名不匹配");
                }
            } else {
                send_response(wsi, "authResponse", "error", "无效的用户ID");
            }
            json_object_put(payload);
        } else {
            send_response(wsi, "authResponse", "error", "Token解析失败");
        }
    } else {
        send_response(wsi, "authResponse", "error", "Token无效或已过期");
    }
}

// 处理Token刷新
static void handle_refresh_token(struct lws *wsi, struct per_session_data__custom *pss,
                                 struct json_object *json) {
    if (!pss->client->is_authenticated) {
        send_response(wsi, "refresh", "error", "请先进行身份认证");
        return;
    }

    struct json_object *token_obj;
    if (!json_object_object_get_ex(json, "token", &token_obj)) {
        send_response(wsi, "refresh", "error", "缺少token字段");
        return;
    }

    const char *old_token = json_object_get_string(token_obj);

    // 验证旧Token
    if (!verify_jwt_token(old_token, secret)) {
        send_response(wsi, "refresh", "error", "旧Token无效");
        return;
    }

    // 生成新Token
    char *new_token = generate_jwt_token(secret, pss->client->user_id,
                                         pss->client->username, "", "");

    // 发送新Token给客户端
    struct json_object *response = json_object_new_object();
    json_object_object_add(response, "action", json_object_new_string("refreshToken"));
    json_object_object_add(response, "status", json_object_new_string("success"));
    json_object_object_add(response, "token", json_object_new_string(new_token));

    send_json(wsi, response);
    json_object_put(response);
    free(new_token);

    lwsl_info("%s Token刷新成功\n", pss->client->username);
}

// 计算在线用户数并广播
static void handle_user_count(struct lws *wsi, VHostData *vhd) {
    struct json_object *broadcast = json_object_new_object();
    json_object_object_add(broadcast, "action", json_object_new_string("userCount"));
    json_object_object_add(broadcast, "status", json_object_new_string("success"));

    char count[20];
    snprintf(count, sizeof(count), "%d", vhd->client_count);
    json_object_object_add(broadcast, "count", json_object_new_string(count));

    const char *broadcast_str = json_object_to_json_string(broadcast);
    // 广播给所有用户(除自己)
    broadcast_message(vhd, broadcast_str, wsi);
    // 在发给自己
    send_json(wsi, broadcast);

    json_object_put(broadcast);
}

// 处理智能家居控制系统消息
static void handle_control_message(struct lws *wsi,
                                   struct json_object *json) {

    struct json_object *content_obj;
    if (json_object_object_get_ex(json, "content", &content_obj)) {
        const char *content = json_object_get_string(content_obj);
        char status[10];
        if (strstr(content, "on")) {
            strcpy(status, "true");
        } else {
            strcpy(status, "false");
        }

        char str_content[50];
        const char __delim[] = "_";
        strcpy(str_content, content);
        char *device;
        device = strtok(str_content, __delim);

        struct json_object *broadcast = json_object_new_object();
        json_object_object_add(broadcast, "action", json_object_new_string("control"));
        json_object_object_add(broadcast, "message", json_object_new_string(content));
        json_object_object_add(broadcast, "device", json_object_new_string(device));
        json_object_object_add(broadcast, "status", json_object_new_string(status));
        printf("status=%s\n", status);
        send_json(wsi, broadcast);

        json_object_put(broadcast);
    } else {
        send_response(wsi, "error", "missing_content", "消息缺少content字段");
    }
}

// 处理系统消息
static void handle_system_message(struct lws *wsi, struct per_session_data__custom *pss, VHostData *vhd,
                                  struct json_object *json) {
    // 检查认证状态
    if (!pss->client->is_authenticated) {
        send_response(wsi, "error", "unauthenticated", "请先进行身份认证");
        return;
    }

    struct json_object *content_obj;
    if (json_object_object_get_ex(json, "content", &content_obj)) {
        const char *content = json_object_get_string(content_obj);

        struct json_object *broadcast = json_object_new_object();
        json_object_object_add(broadcast, "action", json_object_new_string("system"));
        json_object_object_add(broadcast, "content", json_object_new_string(content));

        char timestamp[128];
        time_t now = time(NULL);
        strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
        json_object_object_add(broadcast, "timestamp", json_object_new_string(timestamp));

        const char *broadcast_str = json_object_to_json_string(broadcast);
        broadcast_message(vhd, broadcast_str, wsi);
        json_object_put(broadcast);
    } else {
        send_response(wsi, "error", "missing_content", "消息缺少content字段");
    }
}

static void handle_register(struct lws *wsi, struct per_session_data__custom *pss,
                            struct json_object *json) {
    struct json_object *username_obj, *password_obj, *secretKey_obj;
    if (json_object_object_get_ex(json, "username", &username_obj) &&
        json_object_object_get_ex(json, "password", &password_obj) &&
        json_object_object_get_ex(json, "secretKey", &secretKey_obj)) {

        const char *username = json_object_get_string(username_obj);
        const char *password = json_object_get_string(password_obj);
        const char *secretKey = json_object_get_string(secretKey_obj);

        User user;
        if (select_user_by_username(db, username, &user)) {
            strncpy(user.username, username, sizeof(user.username) - 1);
            strncpy(user.password, password, sizeof(user.password) - 1);
            strncpy(user.secret_key, secretKey, sizeof(user.secret_key) - 1);

            if (strcmp(pss->client->secret_key, secretKey) != 0) {
                send_response(wsi, "register", "error", "秘钥无效");
                lwsl_info("注册失败: 秘钥无效\n");
                return;
            }

            if (insert_user(db, &user) == SQLITE_OK) {
                send_response(wsi, "register", "success", "注册成功");
                lwsl_info("%s 注册成功\n", username);
            } else {
                send_response(wsi, "register", "error", "数据库错误");
                lwsl_info("%s 注册失败: 数据库错误\n", username);
            }
        } else {
            send_response(wsi, "register", "error", "用户名已存在!");
            lwsl_info("%s 注册失败: 用户名已存在\n", username);
        }
    } else {
        send_response(wsi, "register", "error", "缺少必要信息");
        lwsl_info("注册失败: 缺少必要信息\n");
    }
}

// 登录信息处理
static void handle_login(struct lws *wsi, struct per_session_data__custom *pss,
                         VHostData *vhd, struct json_object *json) {
    struct json_object *username_obj, *password_obj;
    if (json_object_object_get_ex(json, "username", &username_obj) &&
        json_object_object_get_ex(json, "password", &password_obj)) {

        const char *username = json_object_get_string(username_obj);
        const char *password = json_object_get_string(password_obj);

        uint8_t authenticated = 0;
        User user;
        if (select_user_by_username(db, username, &user) == SQLITE_OK) {
            if (strcmp(password, user.password) == 0) {
                authenticated = 1;
            }
        }

        if (authenticated) {
            // 设置当前连接的客户端状态
            strncpy(pss->client->username, username, sizeof(pss->client->username) - 1);
            pss->client->is_logged_in = 1;
            pss->client->user_id = user.id;
            pss->client->wsi = wsi;

            struct json_object *response = json_object_new_object();
            json_object_object_add(response, "action", json_object_new_string("login"));
            json_object_object_add(response, "status", json_object_new_string("success"));
            json_object_object_add(response, "username", json_object_new_string(username));
            // 生成token
            char *token = generate_jwt_token(secret, user.id, username, "", "");
            json_object_object_add(response, "token", json_object_new_string(token));

            send_json(wsi, response);
            free(token);

            char broadcast[256];
            snprintf(broadcast, sizeof(broadcast),
                     "{\"action\":\"system\",\"message\":\"%s 已加入聊天室\"}",
                     username);
            broadcast_message(vhd, broadcast, wsi);

            lwsl_info("%s 登录成功\n", username);
        } else {
            send_response(wsi, "login", "error", "用户名或密码错误");
            lwsl_info("登录失败: 用户名或密码错误\n");
        }
    } else {
        send_response(wsi, "login", "error", "缺少用户名或密码");
        lwsl_info("登录失败: 缺少用户名或密码\n");
    }
}

// 退出登录处理
static void handle_logout(struct lws *wsi, struct per_session_data__custom *pss) {
    if (!pss->client->is_logged_in) {
        send_response(wsi, "logout", "error", "用户未登录");
        return;
    }

    // 重置当前连接的登录状态
    pss->client->is_logged_in = 0;
    pss->client->is_authenticated = 0;
    memset(pss->client->username, 0, sizeof(pss->client->username));
    pss->client->user_id = 0;

    send_response(wsi, "logout", "success", "退出登录成功");
}

static void handle_autologin(struct lws *wsi) {
    send_response(wsi, "autologin", "success", "自动登录成功");
}

static void handle_request_secret_key(struct lws *wsi,
                                      struct per_session_data__custom *pss) {
    char secret_key[64];
    generate_secret_key(secret_key, 32);
    strncpy(pss->client->secret_key, secret_key, sizeof(pss->client->secret_key) - 1);
    send_secret_key(wsi, "secretKey", "success", secret_key);
    lwsl_info("为客户端生成秘钥: %s\n", secret_key);
}

static void handle_unknown_action(struct lws *wsi, const char *action) {
    lwsl_warn("未知的action类型: %s\n", action);
    send_response(wsi, "error", "unknown_action", "未知的action类型");
}

// 客户端连接
int init_client_session(struct per_session_data__custom *pss,
                        struct lws *wsi, VHostData *vhd) {
    pss->client = malloc(sizeof(Client));
    if (!pss->client) {
        lwsl_err("内存分配失败\n");
        return 0;
    }
    
    memset(pss->client, 0, sizeof(Client));
    pss->client->wsi = wsi;
    pss->client->is_logged_in = 0;
    pss->client->is_authenticated = 0; // 初始未认证状态
    pss->client->user_id = 0;
    snprintf(pss->client->username, sizeof(pss->client->username),
             "用户%d", vhd->client_count + 1);

    add_client(vhd, pss->client);

    handle_user_count(wsi, vhd);
    lwsl_info("新连接建立，客户端数: %d\n", vhd->client_count);
    return 1;
}

// 客户端连接关闭
void handle_connection_closed(struct per_session_data__custom *pss,
                              VHostData *vhd, struct lws *wsi) {
    if (!pss->client)
        return;

    remove_client(vhd, wsi);
    free(pss->client);
    pss->client = NULL;
    // 广播离开消息
    handle_user_count(wsi, vhd);
    lwsl_info("连接关闭，客户端数: %d\n", vhd->client_count);
}

void handle_action(const char *action, struct lws *wsi,
                   struct per_session_data__custom *pss,
                   VHostData *vhd, struct json_object *json) {
    if (strcmp(action, "message") == 0) {
        handle_message(wsi, pss, vhd, json);
    } else if (strcmp(action, "authenticate") == 0) {
        // 浏览器每次刷新都会调用
        handle_authenticate(wsi, pss, json);
    } else if (strcmp(action, "refreshToken") == 0) {
        handle_refresh_token(wsi, pss, json);
    } else if (strcmp(action, "userCount") == 0) {
        handle_user_count(wsi, vhd);
    } else if (strcmp(action, "system") == 0) {
        handle_system_message(wsi, pss, vhd, json);
    } else if (strcmp(action, "control") == 0) {
        handle_control_message(wsi, json);
    } else if (strcmp(action, "register") == 0) {
        handle_register(wsi, pss, json);
    } else if (strcmp(action, "login") == 0) {
        handle_login(wsi, pss, vhd, json);
    } else if (strcmp(action, "logout") == 0) {
        handle_logout(wsi, pss);
    } else if (strcmp(action, "requestSecretKey") == 0) {
        handle_request_secret_key(wsi, pss);
    } else if (strcmp(action, "autologin") == 0) {
        handle_autologin(wsi);
    } else {
        handle_unknown_action(wsi, action);
    }
}

void handle_received_message(struct lws *wsi,
                             struct per_session_data__custom *pss,
                             VHostData *vhd, void *in, size_t len) {
    char *message = malloc(len + 1);
    if (!message) {
        lwsl_err("内存分配失败\n");
        return;
    }

    memcpy(message, in, len);
    message[len] = '\0';
    lwsl_info("收到消息: %s\n", message);

    struct json_object *json = json_tokener_parse(message);
    if (!json) {
        lwsl_err("无效的JSON格式\n");
        send_response(wsi, "error", "invalid_json", "无效的JSON格式");
        free(message);
        return;
    }

    struct json_object *action_obj;
    if (json_object_object_get_ex(json, "action", &action_obj)) {
        const char *action = json_object_get_string(action_obj);
        handle_action(action, wsi, pss, vhd, json);
    } else {
        send_response(wsi, "error", "missing_action", "消息缺少action字段");
    }

    json_object_put(json);
    free(message);
}